package left42dead;

import java.util.Iterator;
import java.util.List;

/**
 * Vampire class, derives from Character
 */
public class Vampire extends Character
{
    // The vampire thirstiness
    private boolean isThirsty;
    // Vampire probability to become thirsty
    private static final double THIRSTY_PROBABILITY = 0.1;

    /**
     * Constructor of Vampire class. First of all, a vampire isn't thirsty, so
     * he can't bite humans
     * @param healthPoints initial health points
     * @param field Field where he's located
     * @param location The location in the field where he's located
     */
    public Vampire (int healthPoints, Field field, Location location)
    {
        super(healthPoints, field, location);
        isThirsty = false;
    }

    /**
     * This is what the vampires does most of the time
     * @param newCharacters A list to add newly born humans to (not used)
     */
    public void run (List<Character> newCharacters)
    {
        // Search for an human
        Location location = getLocation();
        Location newLocation = hunt(location);

        if (newLocation == null)
        {
            // No food found - try to move to a free location.
            newLocation = getField().freeAdjacentLocation(location);
            if (newLocation != null)
            {
                setLocation(newLocation);
            }
        }
        // See if it was possible to move.
        else if (newLocation != null)
        {
            setLocation(newLocation);
        }
    }

    /**
     * Method called when a vampire decides to bite a human
     * @param h Human who gets bitten by this vampire
     */
    public void bite (Human h)
    {
        // The human has no way to escape. He gets bitten.
        h.setHasBeenBitten(true);
        // Vampire is not thirsty anymore
        isThirsty = false;
    }

    /**
     * Tell the vampire to look for human adjacent to its current location.
     * @param location Where in the field it is located.
     * @return Where human was found, or null if it wasn't.
     */
    public Location hunt (Location location)
    {
        Field field = this.getField();
        List<Location> adjacent = field.adjacentLocations(getLocation());
        Iterator<Location> it = adjacent.iterator();
        
        while (it.hasNext())
        {
            Location where = it.next();
            Object human = field.getObjectAt(where);
            if (human != null && human instanceof Human)
            {
                Human target = (Human) human;
                if (isThirsty && !target.getHasBeenBitten())
                    this.bite(target);
                else
                {
                    attack(target);
                }

                if (target.isDead())
                    return where;

                return null;
            }
        }
        return null;
    }

    /**
     * Method called when a vampire attack another character the character
     * attacked loose 10 HP
     * @param c character attacked by the vampire
     */
    public void attack (Character c)
    {
        c.reduceHealthPoints(10);
    }
    
    /**
     * Method triggered on each character at the end of each turn.
     */
    public void endOfTurn ()
    {
        endOfTurn(Randomizer.getRandom().nextDouble());
    }
    
    /**
     * Method triggered on each character at the end of each turn.
     */
    public void endOfTurn (Double chance)
    {
        // The vampire has chance of becoming thirsty, if he is not already
        if (isThirsty || chance < THIRSTY_PROBABILITY)
        {
            isThirsty = true;
        }
    }

    // Accessors and getters
    public boolean getIsThirsty ()
    {
        return isThirsty;
    }

    public void setIsThirsty (boolean isThirsty)
    {
        this.isThirsty = isThirsty;
    }
}
